using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;

using Weazel.Math;

public class Simulator
{
    
    internal static Controller_euclid_ctl controller_euclid_ctl;
    
    internal static Controller_h_test_euclid controller_h_test_euclid;
    
    internal static OutPort_euclid_gcd outPort_euclid_gcd;
    
    internal static OutPort_test_euclid_m outPort_test_euclid_m;
    
    internal static OutPort_test_euclid_n outPort_test_euclid_n;
    
    internal static Register_euclid_m register_euclid_m;
    
    internal static Register_euclid_n register_euclid_n;
    
    internal static Register_euclid_done register_euclid_done;
    
    internal static Register_euclid_factor register_euclid_factor;
    
    internal static Display_directiveexpression23 display_directiveexpression23;
    
    internal static Display_directiveexpression36 display_directiveexpression36;
    
    internal static Display_directiveexpression48 display_directiveexpression48;
    
    internal static Display_directiveexpression60 display_directiveexpression60;
    
    internal static Display_directiveexpression87 display_directiveexpression87;
    
    internal static Display_directiveexpression96 display_directiveexpression96;
    
    internal static Display_directiveexpression103 display_directiveexpression103;
    
    internal static Display_directiveexpression120 display_directiveexpression120;
    
    internal static Display_directiveexpression133 display_directiveexpression133;
    
    internal static Int32 Cycles;
    
    internal static Int32 CurrentCycle;
    
    internal static List<IOutport> OutportList;
    
    internal static List<IOutport> SortedOutportList;
    
    public static void Initialize()
    {
        Simulator.controller_euclid_ctl = new Controller_euclid_ctl();
        Simulator.controller_h_test_euclid = new Controller_h_test_euclid();
        Simulator.outPort_euclid_gcd = new OutPort_euclid_gcd();
        Simulator.outPort_test_euclid_m = new OutPort_test_euclid_m();
        Simulator.outPort_test_euclid_n = new OutPort_test_euclid_n();
        Simulator.register_euclid_m = new Register_euclid_m();
        Simulator.register_euclid_n = new Register_euclid_n();
        Simulator.register_euclid_done = new Register_euclid_done();
        Simulator.register_euclid_factor = new Register_euclid_factor();
        Simulator.display_directiveexpression23 = new Display_directiveexpression23();
        Simulator.display_directiveexpression36 = new Display_directiveexpression36();
        Simulator.display_directiveexpression48 = new Display_directiveexpression48();
        Simulator.display_directiveexpression60 = new Display_directiveexpression60();
        Simulator.display_directiveexpression87 = new Display_directiveexpression87();
        Simulator.display_directiveexpression96 = new Display_directiveexpression96();
        Simulator.display_directiveexpression103 = new Display_directiveexpression103();
        Simulator.display_directiveexpression120 = new Display_directiveexpression120();
        Simulator.display_directiveexpression133 = new Display_directiveexpression133();
        Simulator.OutportList = new List<IOutport>(3);
        Simulator.SortedOutportList = new List<IOutport>(3);

        // call initializers on the entities in simulation
        Simulator.controller_euclid_ctl.Initialize();
        Simulator.controller_h_test_euclid.Initialize();
        Simulator.outPort_euclid_gcd.Initialize();
        Simulator.outPort_test_euclid_m.Initialize();
        Simulator.outPort_test_euclid_n.Initialize();
        Simulator.register_euclid_m.Initialize();
        Simulator.register_euclid_n.Initialize();
        Simulator.register_euclid_done.Initialize();
        Simulator.register_euclid_factor.Initialize();
        Simulator.display_directiveexpression23.Initialize();
        Simulator.display_directiveexpression36.Initialize();
        Simulator.display_directiveexpression48.Initialize();
        Simulator.display_directiveexpression60.Initialize();
        Simulator.display_directiveexpression87.Initialize();
        Simulator.display_directiveexpression96.Initialize();
        Simulator.display_directiveexpression103.Initialize();
        Simulator.display_directiveexpression120.Initialize();
        Simulator.display_directiveexpression133.Initialize();
    }
    
    public static void Run()
    {
        int i = 0;
        IOutport outport;
        for (
        ; (Simulator.CurrentCycle < Simulator.Cycles); 
        )
        {
            // evaluate controllers
            Simulator.controller_euclid_ctl.Evaluate();
            Simulator.controller_h_test_euclid.Evaluate();

            for (i = 0; (i < Simulator.OutportList.Count); i = (i + 1))
            {
                outport = Simulator.OutportList[i];
                if ((outport._Color == Color.White))
                {
                    Simulator.DfsVisit(ref outport);
                }
            }

            for (i = 0; (i < Simulator.SortedOutportList.Count); i = (i + 1))
            {
                Simulator.SortedOutportList[i].Evaluate();
            }

            // evaluate registers
            Simulator.register_euclid_m.Evaluate();
            Simulator.register_euclid_n.Evaluate();
            Simulator.register_euclid_done.Evaluate();
            Simulator.register_euclid_factor.Evaluate();

            // evaluate ipblock inports

            // evaluate directives
            Simulator.display_directiveexpression23.Evaluate();
            Simulator.display_directiveexpression36.Evaluate();
            Simulator.display_directiveexpression48.Evaluate();
            Simulator.display_directiveexpression60.Evaluate();
            Simulator.display_directiveexpression87.Evaluate();
            Simulator.display_directiveexpression96.Evaluate();
            Simulator.display_directiveexpression103.Evaluate();
            Simulator.display_directiveexpression120.Evaluate();
            Simulator.display_directiveexpression133.Evaluate();

            // run tracers

            // update register values
            Simulator.register_euclid_m.Tick();
            Simulator.register_euclid_n.Tick();
            Simulator.register_euclid_done.Tick();
            Simulator.register_euclid_factor.Tick();

            // prepare for next cycle
            for (i = 0; (i < Simulator.SortedOutportList.Count); i = (i + 1))
            {
                Simulator.SortedOutportList[i]._Color = Color.White;
            }

            Simulator.OutportList.Clear();
            Simulator.SortedOutportList.Clear();
            Simulator.CurrentCycle = (Simulator.CurrentCycle + 1);
        }
    }
    
    public static void DfsVisit(ref IOutport outport)
    {
        int i;
        IOutport child;
        IOutport[] children = outport.GetDependentOutports();
        outport._Color = Color.Gray;
        for (i = 0; (i < children.Length); i = (i + 1))
        {
            child = children[i];
            if ((child._Color == Color.White))
            {
                Simulator.DfsVisit(ref child);
            }
            else
            {
                if ((child._Color == Color.Gray))
                {
                    throw new ApplicationException("Signal in combinatorial loop.");
                }
            }
        }
        outport._Color = Color.Black;
        Simulator.SortedOutportList.Add(outport);
    }
}
